package com.ycky.batchProcess;

import lombok.Data;

import java.util.Map;

/**
 * @description: 发布缓冲区
 * @author: cjj
 * @time: 2025/3/18 10:59
 */
@Data
public class ProgressBuffer {

    private int bufferCount;
    private long lastFlushTime;
    private Map<String, Object> lastProgress;
    private final Long userId;
    private Long startTime;
    private double currentSpeed; // 当前处理速率(records/second)

    // 缓冲区大小阈值
    private static final int BUFFER_THRESHOLD = 100;

    // 缓冲区刷新时间间隔(毫秒)
    private static final long FLUSH_INTERVAL = 1000;

    public void update(Map<String, Object> progress) {
        this.lastProgress = progress;
        this.bufferCount++;
    }

    public boolean shouldFlush(int current, int total) {
        // 条件1: 缓冲区达到阈值
        if (this.bufferCount >= BUFFER_THRESHOLD) {
            return true;
        }

        // 条件2: 距离上次刷新超过时间间隔
        long now = System.currentTimeMillis();
        if (now - this.lastFlushTime >= FLUSH_INTERVAL) {
            return true;
        }

        // 条件3: 是最后一条记录
        return current >= total;
    }
    /**
     * 更新处理速率
     *
     * @param speed 当前处理速率(records/second)
     */
    public void updateSpeed(double speed) {
        this.currentSpeed = this.currentSpeed == 0 ?
                speed : (this.currentSpeed * 0.7 + speed * 0.3);
    }

    public String calculateRemainingTime(int current, int total, int publishRate) {
        // 使用实际速率和期望速率的较小值作为预估速率
        double estimatedSpeed = this.currentSpeed;
        if (estimatedSpeed <= 0) {
            estimatedSpeed = publishRate; // 如果还没有速率数据,使用期望速率
        }

        // 计算剩余时间
        int remaining = total - current;
        long remainingTime = (long) (remaining / estimatedSpeed * 1000); // 转换为毫秒

        // 格式化剩余时间
        if (remainingTime < 1000) {
            return "即将完成";
        }
        if (remainingTime < 60000) {
            return String.format("约%d秒", remainingTime / 1000);
        }
        return String.format("约%d分%d秒",
                remainingTime / 60000,
                (remainingTime % 60000) / 1000);
    }
}